package business_logic.game_elements;


import java.util.Collection;
import java.util.EnumSet;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import model.elements.PlayerCharacter;
import model.elements.attributes.Coordinate2D;
import model.elements.commands.*;
import model.elements.states.weapon.*;
import model.exceptions.MaxAmmoUsed;
import model.exceptions.ModelExceptions;

import business_logic.GameElement;
import business_logic.Tile;
import business_logic.view.GameViewIdentifier;

public class Bombita extends PlayerCharacter implements GameElement
{
	
	private static final int 	BombitaStartingAmmo = 3;
	private static final double BombitaBaseSpeed 	= 0.5;

	int m_counter = 0;
    
    private static final Collection<GameViewIdentifier> m_viewIdentifiers = 
            EnumSet.of(GameViewIdentifier.SPRITE_BOMBITA_RODRIGUEZ);
    
	public Bombita(Coordinate2D startingPosition) throws ModelExceptions
	{
		super(startingPosition, BombitaBaseSpeed);
		super.setWeapon(new BombEquipped(BombitaStartingAmmo));
		//super.setWeapon(new CannonEquipped(1, this));
	}

	public Collection<GameViewIdentifier> getViewIdentifiers()
    {
        return m_viewIdentifiers;
    }
	
	public boolean canAddCommands()
	{
		return  !( m_counter+1 < Tile.speedToTickets( this.getSpeed().getValue() ) );
	}
	
	@Override
	public void addCommand( ElementCommand command )
	{
	    //TODO esto es un fix para el bug donde si vario la velocidad, con el upgrade de velocidad
		// no maneja bien una asignacion de comando de usar arma nuevo
		if( m_lifeState.getCommand().getClass().equals( ElementUseWeapon.class ) ) return;
		
	    if ( canAddCommands() )
	    {	    	
		   m_lifeState.setCommand(command);
		   m_counter = 0;
	    }
	}
	
	@Override
	public void setSpeedMultiplier( double multiplier ) 
	{
		m_speed.setMultiplier(multiplier);
	}

    @Override
    public void vivir()
    {
        try
		{
			this.update();
	         m_counter++; 
		}
        catch ( MaxAmmoUsed e )
        {
            // Esto esta bien, no hagas nada
        }
        catch ( ModelExceptions e )
		{
			e.printStackTrace();
		}
    }
    
    @Override
    public void update() throws ModelExceptions
    {
        m_lifeState.getCommand().execute( this );
        this.addCommand(new ElementDoesNothing());
    }

    @Override
    public int getX()
    {
        return Tile.pixelToTile( m_currentPosition.getRealX() );
    }

    @Override
    public int getY()
    {
        return Tile.pixelToTile( m_currentPosition.getRealY() );
    }
    
	private boolean		BombitaWinning		= false;

    public boolean isBombitaWinning()
	{
		return BombitaWinning;
	}

	public void setBombitaWinning(boolean bombitaWinning)
	{
		BombitaWinning = ( BombitaWinning || bombitaWinning );
	}

    private static final long m_serialVersionUID = 1L;
    
    @Override
    public Element save()
    {
        Element elem = DocumentHelper.createElement( this.getClass().getName() );
        elem.addAttribute( "serialVersion", m_serialVersionUID+"" );
        elem.addAttribute( "x", Math.floor( this.getPosition().getRealX() ) +"" );
        elem.addAttribute( "y", Math.floor( this.getPosition().getRealY() ) +"" );
        
        elem.addAttribute( "speed_multiplier", this.m_speed.getMultiplier() +"" );
        
        elem.addAttribute( "weapon", this.m_equippedWeapon.getClass().getName() +"" );
        
        return elem;
    }
    
    public Bombita( Element elem ) throws ModelExceptions
    {
        super
        (
            new Coordinate2D
            (
                Double.parseDouble(elem.attributeValue("x")),
                Double.parseDouble(elem.attributeValue("y"))
            ),
            BombitaBaseSpeed
        );

        try
        {
            super.setWeapon
            (
                (ElementWeaponState) Class.forName( elem.attributeValue("weapon") ).getDeclaredConstructor( int.class ).newInstance(BombitaStartingAmmo)
            );
        }
        catch (Exception e)
        {
            //super.setWeapon(new BombEquipped(BombitaStartingAmmo));
        }

        this.setSpeedMultiplier( Double.parseDouble(elem.attributeValue("speed_multiplier")) );
    }
    
}
